Popular Searches
Popular Course Categories
Popular Courses

Dynamic XPath

Advanced Selenium

<div class="selenium-notes">

<h1>Dynamic XPath in Selenium</h1>

<p><strong>Dynamic XPath</strong> is an advanced XPath technique used in Selenium WebDriver to locate web elements whose attributes, values, positions, or surrounding HTML structure change dynamically at runtime. Dynamic XPath helps automation testers create flexible and reliable locators for modern web applications where static attributes such as IDs, class names, or text values may change frequently.</p>

<p>In real-world Selenium automation, dynamic elements are common in applications built with JavaScript frameworks such as React, Angular, Vue, and other dynamic web technologies. Dynamic XPath techniques allow testers to locate such elements by using stable attributes, partial matches, relationships between elements, and XPath functions.</p>

<p>Dynamic XPath is especially useful for login forms, search results, e-commerce product lists, tables, menus, buttons, dynamic IDs, changing class names, and elements whose position changes depending on application data.</p>

<p><strong>Course Resource:</strong> <a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training</a> | <a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Register for Course Demo</a></p>

<hr>

<h2>1. What is XPath?</h2>

<p><strong>XPath</strong> stands for XML Path Language. In Selenium, XPath is commonly used to identify elements in an HTML DOM when other locators such as ID, name, class name, or CSS selector are not suitable or sufficiently stable.</p>

<p>XPath allows Selenium to navigate through the HTML structure and identify elements using attributes, text, hierarchy, relationships, and functions.</p>

<pre><code>driver.findElement(By.xpath("//input[@id='username']")).sendKeys("admin");</code></pre>

<p>Here, Selenium searches for an <code>input</code> element whose <code>id</code> attribute is <code>username</code>.</p>

<hr>

<h2>2. What is Dynamic XPath?</h2>

<p>Dynamic XPath is an XPath expression designed to locate elements even when some properties of the element change dynamically.</p>

<p>For example, suppose a web application generates the following IDs:</p>

<pre><code>username_12345

username_67891

username_54321</code></pre>

<p>A static XPath such as:</p>

<pre><code>//input[@id='username_12345']</code></pre>

<p>may fail when the application generates a different ID. A dynamic XPath can identify the stable part of the ID:</p>

<pre><code>//input[contains(@id,'username_')]</code></pre>

<p>This XPath can match elements whose ID starts with or contains the stable portion <code>username_</code>.</p>

<hr>

<h2>3. Why is Dynamic XPath Important?</h2>

<p>Dynamic XPath is important because modern web applications frequently generate dynamic attributes. A locator that depends on an unstable value can cause automation scripts to fail.</p>

<ul>

<li>Handles dynamically generated IDs.</li>

<li>Handles changing class names.</li>

<li>Locates elements using partial attribute values.</li>

<li>Supports dynamic text matching.</li>

<li>Allows navigation through parent-child relationships.</li>

<li>Supports locating elements using sibling relationships.</li>

<li>Helps automate dynamic tables and lists.</li>

<li>Improves locator flexibility.</li>

<li>Can reduce dependence on unstable attributes.</li>

<li>Is useful for complex Selenium automation frameworks.</li>

</ul>

<hr>

<h2>4. Static XPath vs Dynamic XPath</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Static XPath</th><th>Dynamic XPath</th></tr>

<tr><td>Uses exact values.</td><td>Can use partial or flexible values.</td></tr>

<tr><td>More dependent on fixed attributes.</td><td>Can work with changing attributes.</td></tr>

<tr><td>Simple to create.</td><td>Requires more XPath knowledge.</td></tr>

<tr><td>May fail when values change.</td><td>Can remain valid when dynamic values change.</td></tr>

<tr><td>Suitable for stable elements.</td><td>Suitable for dynamic elements.</td></tr>

</table>

<hr>

<h2>5. Basic XPath Syntax</h2>

<p>The basic XPath syntax is:</p>

<pre><code>//tagname[@attribute='value']</code></pre>

<p>Example:</p>

<pre><code>//input[@id='username']</code></pre>

<p>Another example:</p>

<pre><code>//button[@type='submit']</code></pre>

<p>Dynamic XPath techniques extend this basic syntax using functions and relationships.</p>

<hr>

<h2>6. Absolute XPath vs Relative XPath</h2>

<h3>Absolute XPath</h3>

<p>Absolute XPath starts from the root of the HTML document and follows the complete hierarchy.</p>

<pre><code>/html/body/div/div/form/input</code></pre>

<p>Absolute XPath is generally fragile because any change in the HTML hierarchy can break the locator.</p>

<h3>Relative XPath</h3>

<p>Relative XPath starts from a specific location in the DOM and generally begins with <code>//</code>.</p>

<pre><code>//input[@id='username']</code></pre>

<p>Relative XPath is usually more practical for Selenium automation because it can focus on meaningful attributes and relationships rather than the complete DOM hierarchy.</p>

<hr>

<h2>7. XPath with contains()</h2>

<p>The <strong>contains()</strong> function is one of the most commonly used techniques for creating dynamic XPath expressions.</p>

<p>Syntax:</p>

<pre><code>//tag[contains(@attribute,'partialValue')]</code></pre>

<p>Example:</p>

<pre><code>//input[contains(@id,'username')]</code></pre>

<p>If the actual ID changes from:</p>

<pre><code>username_123

username_456

username_789</code></pre>

<p>the XPath can still locate the element because it searches for the stable portion <code>username</code>.</p>

<hr>

<h2>8. contains() with Class Attribute</h2>

<p>Dynamic class names are common in modern web applications.</p>

<pre><code>//button[contains(@class,'login')]</code></pre>

<p>This can match a button such as:</p>

<pre><code>&lt;button class="btn login primary"&gt;Login&lt;/button&gt;</code></pre>

<p>Another example:</p>

<pre><code>//div[contains(@class,'product-card')]</code></pre>

<hr>

<h2>9. contains() with Text</h2>

<p>The <code>contains()</code> function can also be combined with <code>text()</code>.</p>

<pre><code>//button[contains(text(),'Login')]</code></pre>

<p>This can be useful when the complete button text is dynamic but contains a stable word.</p>

<p>For example:</p>

<pre><code>&lt;button&gt;Login Now&lt;/button&gt;</code></pre>

<p>XPath:</p>

<pre><code>//button[contains(text(),'Login')]</code></pre>

<hr>

<h2>10. XPath text() Function</h2>

<p>The <strong>text()</strong> function is used to locate elements based on their visible text.</p>

<pre><code>//button[text()='Login']</code></pre>

<p>This XPath looks for a button whose text exactly matches <code>Login</code>.</p>

<p>For dynamic text, combine <code>text()</code> with <code>contains()</code>:</p>

<pre><code>//button[contains(text(),'Log')]</code></pre>

<hr>

<h2>11. normalize-space()</h2>

<p>The <strong>normalize-space()</strong> function is useful when text contains extra spaces or inconsistent whitespace.</p>

<pre><code>//button[normalize-space()='Login']</code></pre>

<p>For example, it can help locate an element when the HTML contains unexpected whitespace around the visible text.</p>

<pre><code>//button[normalize-space()='Submit']</code></pre>

<p>This is often more reliable than an exact text comparison when whitespace formatting is inconsistent.</p>

<hr>

<h2>12. starts-with() Function</h2>

<p>The <strong>starts-with()</strong> function identifies elements where an attribute begins with a specific value.</p>

<p>Syntax:</p>

<pre><code>//tag[starts-with(@attribute,'value')]</code></pre>

<p>Example:</p>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<p>If the application generates:</p>

<pre><code>user_123

user_456

user_789</code></pre>

<p>the XPath can locate the elements using their common prefix.</p>

<hr>

<h2>13. contains() vs starts-with()</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Function</th><th>Purpose</th><th>Example</th></tr>

<tr><td>contains()</td><td>Matches a value appearing anywhere inside an attribute.</td><td><code>contains(@id,'user')</code></td></tr>

<tr><td>starts-with()</td><td>Matches a value at the beginning of an attribute.</td><td><code>starts-with(@id,'user_')</code></td></tr>

</table>

<hr>

<h2>14. Dynamic XPath with Multiple Attributes</h2>

<p>Multiple attributes can be combined using the <strong>and</strong> operator.</p>

<pre><code>//input[@type='text' and @name='username']</code></pre>

<p>This approach is useful when one attribute is not unique.</p>

<p>Example:</p>

<pre><code>//input[contains(@class,'form-control') and @type='text']</code></pre>

<hr>

<h2>15. Dynamic XPath with OR</h2>

<p>The <strong>or</strong> operator can be used when an element can be identified using either of two conditions.</p>

<pre><code>//input[@id='username' or @name='username']</code></pre>

<p>This can be useful when the same application may render slightly different markup in different situations.</p>

<hr>

<h2>16. Dynamic XPath Using Parent</h2>

<p>XPath can navigate from a child element to its parent using <code>..</code> or the <code>parent::</code> axis.</p>

<pre><code>//input[@id='username']/parent::div</code></pre>

<p>This technique is useful when the child has a stable attribute but the desired clickable or container element is the parent.</p>

<hr>

<h2>17. Dynamic XPath Using Child</h2>

<p>The <code>child::</code> axis can be used to navigate from a parent to its child elements.</p>

<pre><code>//div[@id='loginForm']/child::input</code></pre>

<p>A shorter equivalent can often be:</p>

<pre><code>//div[@id='loginForm']//input</code></pre>

<hr>

<h2>18. Dynamic XPath Using Descendant</h2>

<p>The <strong>descendant</strong> relationship is useful when the target element can appear at different levels below a known parent.</p>

<pre><code>//div[@id='loginForm']//input[@name='username']</code></pre>

<p>The double slash after the parent allows Selenium to search through descendant elements.</p>

<hr>

<h2>19. Dynamic XPath Using Ancestor</h2>

<p>The <strong>ancestor</strong> axis can locate a parent or higher-level container of an element.</p>

<pre><code>//input[@name='username']/ancestor::form</code></pre>

<p>This can be useful when a child element is easy to identify but the required container is higher in the DOM hierarchy.</p>

<hr>

<h2>20. Dynamic XPath Using Following-Sibling</h2>

<p>The <strong>following-sibling</strong> axis locates elements that appear after the current element at the same hierarchical level.</p>

<pre><code>//label[text()='Username']/following-sibling::input</code></pre>

<p>This technique is useful when a label has stable text but the input does not have a reliable unique attribute.</p>

<hr>

<h2>21. Dynamic XPath Using Preceding-Sibling</h2>

<p>The <strong>preceding-sibling</strong> axis locates an element that appears before the current element.</p>

<pre><code>//input[@name='username']/preceding-sibling::label</code></pre>

<p>This can be useful for relationships between labels, fields, icons, and other controls.</p>

<hr>

<h2>22. Dynamic XPath Using Following</h2>

<p>The <strong>following</strong> axis can locate elements appearing later in the document relative to the current node.</p>

<pre><code>//label[text()='Username']/following::input[1]</code></pre>

<p>The positional index <code>[1]</code> can be used when the first matching element is required.</p>

<hr>

<h2>23. Dynamic XPath Using Preceding</h2>

<p>The <strong>preceding</strong> axis can locate elements appearing before the current element in the document.</p>

<pre><code>//button[text()='Submit']/preceding::input[1]</code></pre>

<hr>

<h2>24. Dynamic XPath with Index</h2>

<p>XPath indexes can be used when multiple elements match the same expression.</p>

<pre><code>(//input[@type='text'])[1]</code></pre>

<p>Another example:</p>

<pre><code>(//button[contains(@class,'btn')])[2]</code></pre>

<p>Indexes should be used carefully because DOM order can change when the application is modified.</p>

<hr>

<h2>25. Dynamic XPath with Position</h2>

<p>The <strong>position()</strong> function can identify an element based on its position within a node set.</p>

<pre><code>//table//tr[position()=2]</code></pre>

<p>This identifies the second matching table row.</p>

<hr>

<h2>26. Dynamic XPath with last()</h2>

<p>The <strong>last()</strong> function can locate the last matching element.</p>

<pre><code>//table//tr[last()]</code></pre>

<p>This is useful when the last row or last matching item is required.</p>

<hr>

<h2>27. Dynamic XPath for Tables</h2>

<p>Dynamic XPath is particularly useful for automating HTML tables where the row and column positions change according to application data.</p>

<p>Example table:</p>

<pre><code>&lt;table&gt;

    &lt;tr&gt;

        &lt;th&gt;Product&lt;/th&gt;

        &lt;th&gt;Price&lt;/th&gt;

    &lt;/tr&gt;

    &lt;tr&gt;

        &lt;td&gt;Laptop&lt;/td&gt;

        &lt;td&gt;$1000&lt;/td&gt;

    &lt;/tr&gt;

&lt;/table&gt;</code></pre>

<p>XPath for the Laptop row:</p>

<pre><code>//table//tr[td[text()='Laptop']]</code></pre>

<p>XPath for the price associated with Laptop:</p>

<pre><code>//table//tr[td[text()='Laptop']]/td[2]</code></pre>

<hr>

<h2>28. Dynamic XPath for E-Commerce Products</h2>

<p>E-commerce applications frequently display products using repeated cards. Dynamic XPath can locate a specific product based on its name.</p>

<pre><code>//div[contains(@class,'product-card')][.//h2[text()='Laptop']]</code></pre>

<p>To locate the product's button:</p>

<pre><code>//div[contains(@class,'product-card')][.//h2[text()='Laptop']]//button</code></pre>

<p>This approach avoids depending on the product's changing position in the page.</p>

<hr>

<h2>29. Dynamic XPath for Product Price</h2>

<p>If the product name is stable but the price changes, the product can be located first and its price can then be selected relative to it.</p>

<pre><code>//div[contains(@class,'product-card')][.//h2[text()='Laptop']]//*[contains(@class,'price')]</code></pre>

<hr>

<h2>30. Dynamic XPath for Login Page</h2>

<p>Consider a login form:</p>

<pre><code>&lt;input type="text" id="user_12345"&gt;

&lt;input type="password" id="pass_67890"&gt;

&lt;button id="login_98765"&gt;Login&lt;/button&gt;</code></pre>

<p>Dynamic XPath expressions can be:</p>

<pre><code>//input[starts-with(@id,'user_')]

//input[starts-with(@id,'pass_')]

//button[contains(@id,'login_')]</code></pre>

<hr>

<h2>31. Dynamic XPath for Buttons</h2>

<p>Buttons may contain changing classes or generated IDs. A stable text or partial attribute can be used.</p>

<pre><code>//button[contains(text(),'Submit')]</code></pre>

<p>Or:</p>

<pre><code>//button[contains(@class,'submit')]</code></pre>

<p>Or using multiple conditions:</p>

<pre><code>//button[contains(@class,'btn') and contains(text(),'Submit')]</code></pre>

<hr>

<h2>32. Dynamic XPath for Links</h2>

<p>Links can also contain dynamic URLs or changing text.</p>

<pre><code>//a[contains(text(),'Profile')]</code></pre>

<p>For dynamic href values:</p>

<pre><code>//a[contains(@href,'profile')]</code></pre>

<p>If the URL begins with a stable prefix:</p>

<pre><code>//a[starts-with(@href,'/profile')]</code></pre>

<hr>

<h2>33. Dynamic XPath for Checkboxes</h2>

<p>Checkboxes can be located using stable surrounding text or attributes.</p>

<pre><code>//label[contains(text(),'Accept Terms')]/input</code></pre>

<p>Another example:</p>

<pre><code>//input[@type='checkbox' and contains(@name,'terms')]</code></pre>

<hr>

<h2>34. Dynamic XPath for Radio Buttons</h2>

<pre><code>//input[@type='radio' and @value='male']</code></pre>

<p>For partial values:</p>

<pre><code>//input[@type='radio' and contains(@value,'male')]</code></pre>

<hr>

<h2>35. Dynamic XPath for Dropdown Options</h2>

<p>Dynamic XPath can be used to locate a specific option based on its visible text.</p>

<pre><code>//select[@id='country']/option[text()='India']</code></pre>

<p>For partial text:</p>

<pre><code>//select[@id='country']/option[contains(text(),'Ind')]</code></pre>

<hr>

<h2>36. Dynamic XPath for Search Results</h2>

<p>Search result pages often contain repeated elements. A dynamic XPath can locate a result using its title.</p>

<pre><code>//div[contains(@class,'search-result')][.//h3[contains(text(),'Selenium')]]</code></pre>

<p>This is more flexible than selecting a result by its fixed position.</p>

<hr>

<h2>37. Dynamic XPath for Menus</h2>

<p>Navigation menus can be located using visible text.</p>

<pre><code>//nav//a[contains(text(),'Products')]</code></pre>

<p>If the menu contains dynamic classes:</p>

<pre><code>//nav//*[contains(@class,'menu-item')]//a[contains(text(),'Products')]</code></pre>

<hr>

<h2>38. Dynamic XPath with Multiple Conditions</h2>

<p>Multiple conditions can make a dynamic XPath more specific.</p>

<pre><code>//input[

    @type='text'

    and contains(@class,'form-control')

    and starts-with(@id,'user_')

]</code></pre>

<p>In a compact Selenium expression:</p>

<pre><code>driver.findElement(By.xpath("//input[@type='text' and contains(@class,'form-control') and starts-with(@id,'user_')]"));</code></pre>

<hr>

<h2>39. Dynamic XPath with not()</h2>

<p>The <strong>not()</strong> function can exclude unwanted elements.</p>

<pre><code>//input[@type='text' and not(@disabled)]</code></pre>

<p>This expression can help identify text inputs that are not disabled.</p>

<hr>

<h2>40. Dynamic XPath Using @ Attribute</h2>

<p>The <code>@</code> symbol is used to reference an HTML attribute.</p>

<pre><code>//input[@name='username']

//button[@type='submit']

//a[@href='/login']</code></pre>

<p>Attributes commonly used in dynamic XPath include:</p>

<ul>

<li>id</li>

<li>name</li>

<li>class</li>

<li>type</li>

<li>value</li>

<li>href</li>

<li>title</li>

<li>placeholder</li>

<li>aria-label</li>

<li>data-* attributes</li>

</ul>

<hr>

<h2>41. Dynamic XPath Using Custom Attributes</h2>

<p>Modern applications often provide custom attributes such as <code>data-testid</code>, <code>data-id</code>, or <code>data-test</code>.</p>

<pre><code>//button[@data-testid='login-button']</code></pre>

<p>When these attributes are intentionally designed for testing and remain stable, they can provide reliable locators.</p>

<hr>

<h2>42. Dynamic XPath Using aria-label</h2>

<p>Accessibility attributes such as <code>aria-label</code> can sometimes provide stable element identification.</p>

<pre><code>//button[@aria-label='Search']</code></pre>

<p>For partial values:</p>

<pre><code>//button[contains(@aria-label,'Search')]</code></pre>

<hr>

<h2>43. Dynamic XPath with normalize-space() and contains()</h2>

<p>Both functions can be combined when visible text contains inconsistent whitespace and additional text.</p>

<pre><code>//button[contains(normalize-space(),'Submit')]</code></pre>

<p>This can be useful when the displayed text contains additional spaces or formatting.</p>

<hr>

<h2>44. Dynamic XPath for Nested Elements</h2>

<p>Nested elements can be located by first identifying a stable parent and then searching inside it.</p>

<pre><code>//div[@id='loginForm']//input[contains(@name,'user')]</code></pre>

<p>This strategy is useful when multiple elements on the page have similar attributes.</p>

<hr>

<h2>45. Dynamic XPath Using Parent-Child Relationship</h2>

<p>Consider:</p>

<pre><code>&lt;div class="form-group"&gt;

    &lt;label&gt;Username&lt;/label&gt;

    &lt;input type="text"&gt;

&lt;/div&gt;</code></pre>

<p>The input can be located relative to the label:</p>

<pre><code>//label[text()='Username']/following-sibling::input</code></pre>

<hr>

<h2>46. Dynamic XPath Using Sibling Relationship</h2>

<p>Sibling-based XPath is useful when one element has stable text and the target element is next to it.</p>

<pre><code>//span[text()='Email']/following-sibling::input</code></pre>

<p>Another example:</p>

<pre><code>//input[@name='email']/preceding-sibling::label</code></pre>

<hr>

<h2>47. Dynamic XPath for Repeated Elements</h2>

<p>When many elements have the same structure, a parent-child relationship can distinguish the required element.</p>

<pre><code>//div[contains(@class,'user-card')][.//span[text()='John']]//button[contains(text(),'Edit')]</code></pre>

<p>This expression first identifies John's card and then finds the Edit button inside that card.</p>

<hr>

<h2>48. Dynamic XPath for Dynamic IDs</h2>

<p>Dynamic IDs are one of the most common reasons for using dynamic XPath.</p>

<p>Suppose the application generates:</p>

<pre><code>input_1001

input_1002

input_1003</code></pre>

<p>Instead of:</p>

<pre><code>//input[@id='input_1001']</code></pre>

<p>Use:</p>

<pre><code>//input[starts-with(@id,'input_')]</code></pre>

<hr>

<h2>49. Dynamic XPath for Changing Class Names</h2>

<p>Suppose an application generates:</p>

<pre><code>btn_primary_123

btn_primary_456

btn_primary_789</code></pre>

<p>A partial class match can be used:</p>

<pre><code>//button[contains(@class,'btn_primary')]</code></pre>

<p>When classes contain multiple tokens, testers should ensure that the selected partial value is sufficiently specific.</p>

<hr>

<h2>50. Dynamic XPath for Changing Text</h2>

<p>If an element's text contains a stable word but additional text changes, use <code>contains()</code>.</p>

<pre><code>//div[contains(text(),'Welcome')]</code></pre>

<p>For example:</p>

<pre><code>Welcome John

Welcome David

Welcome Robert</code></pre>

<p>All may be matched using:</p>

<pre><code>//div[contains(text(),'Welcome')]</code></pre>

<hr>

<h2>51. Dynamic XPath with Selenium WebDriver</h2>

<p>Once a dynamic XPath is created, it can be passed to Selenium's <code>By.xpath()</code> locator.</p>

<pre><code>WebElement username = driver.findElement(

    By.xpath("//input[starts-with(@id,'user_')]")

);

 

username.sendKeys("admin");</code></pre>

<p>Another example:</p>

<pre><code>driver.findElement(

    By.xpath("//button[contains(text(),'Login')]")

).click();</code></pre>

<hr>

<h2>52. Dynamic XPath with Explicit Wait</h2>

<p>Creating a correct XPath is only one part of reliable automation. Dynamic applications may also require synchronization.</p>

<pre><code>WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

 

WebElement loginButton = wait.until(

    ExpectedConditions.elementToBeClickable(

        By.xpath("//button[contains(text(),'Login')]")

    )

);

 

loginButton.click();</code></pre>

<p>A stable dynamic XPath combined with an appropriate explicit wait can make Selenium automation more reliable.</p>

<hr>

<h2>53. Dynamic XPath for AJAX Elements</h2>

<p>AJAX-based applications may add or update elements without a complete page refresh. Their attributes or positions may change dynamically.</p>

<p>For such elements, use:</p>

<ul>

<li>Stable attributes.</li>

<li>Partial attribute matching.</li>

<li>Text-based identification.</li>

<li>Parent-child relationships.</li>

<li>Explicit waits.</li>

<li>Meaningful application-specific attributes.</li>

</ul>

<hr>

<h2>54. Dynamic XPath for React Applications</h2>

<p>React applications may generate dynamic classes, IDs, and nested DOM structures. Instead of relying on generated values, look for stable attributes such as testing attributes, accessibility attributes, meaningful text, or predictable relationships.</p>

<pre><code>//button[@data-testid='login-button']</code></pre>

<p>Or:</p>

<pre><code>//button[contains(@aria-label,'Login')]</code></pre>

<p>The exact locator should depend on the application's DOM and the stability of the selected attribute.</p>

<hr>

<h2>55. Dynamic XPath for Angular Applications</h2>

<p>Angular applications can also contain dynamically generated attributes and repeated components.</p>

<p>A stable custom attribute can be preferable:</p>

<pre><code>//button[@data-test='submit']</code></pre>

<p>When no stable attribute is available, relationship-based XPath can be used.</p>

<pre><code>//label[normalize-space()='Username']/following-sibling::input</code></pre>

<hr>

<h2>56. Dynamic XPath for Vue Applications</h2>

<p>Vue applications can also update DOM elements dynamically. The same general XPath principles apply: identify stable attributes, meaningful text, and reliable relationships.</p>

<pre><code>//button[contains(@class,'login-button')]</code></pre>

<hr>

<h2>57. Dynamic XPath for Pagination</h2>

<p>Pagination controls often contain changing page numbers.</p>

<pre><code>//a[normalize-space()='3']</code></pre>

<p>For a dynamic page number supplied by Java:</p>

<pre><code>String pageNumber = "3";

 

driver.findElement(

    By.xpath("//a[normalize-space()='" + pageNumber + "']")

).click();</code></pre>

<hr>

<h2>58. Dynamic XPath for Dynamic Table Rows</h2>

<p>Suppose a table contains users and their statuses. To locate the row for a specific user:</p>

<pre><code>//table//tr[td[normalize-space()='John']]</code></pre>

<p>To click an action button inside that row:</p>

<pre><code>//table//tr[td[normalize-space()='John']]//button[contains(text(),'Edit')]</code></pre>

<p>This is a powerful technique for handling data-driven tables.</p>

<hr>

<h2>59. Dynamic XPath with Java Variables</h2>

<p>XPath expressions can be dynamically constructed using Java variables.</p>

<pre><code>String productName = "Laptop";

 

String xpath = "//div[contains(@class,'product-card')][.//h2[normalize-space()='" 

        + productName + "']]";

 

driver.findElement(By.xpath(xpath)).click();</code></pre>

<p>This allows the same automation logic to work with different data.</p>

<hr>

<h2>60. Dynamic XPath for Data-Driven Testing</h2>

<p>Dynamic XPath works well with TestNG Data Providers. Test data can be used to construct XPath expressions dynamically.</p>

<pre><code>@DataProvider(name = "products")

public Object[][] products() {

    return new Object[][] {

        {"Laptop"},

        {"Mobile"},

        {"Headphones"}

    };

}

 

@Test(dataProvider = "products")

public void productTest(String product) {

 

    String xpath =

        "//div[contains(@class,'product-card')][.//h2[normalize-space()='"

        + product + "']]";

 

    driver.findElement(By.xpath(xpath)).click();

}</code></pre>

<hr>

<h2>61. Dynamic XPath and Page Object Model</h2>

<p>Dynamic XPath should generally be maintained inside Page Object classes rather than scattered throughout test methods. This keeps locator logic centralized and makes framework maintenance easier.</p>

<pre><code>public class ProductPage {

 

    private WebDriver driver;

 

    public ProductPage(WebDriver driver) {

        this.driver = driver;

    }

 

    public void selectProduct(String productName) {

 

        String xpath =

            "//div[contains(@class,'product-card')][.//h2[normalize-space()='"

            + productName + "']]";

 

        driver.findElement(By.xpath(xpath)).click();

    }

}</code></pre>

<hr>

<h2>62. Dynamic XPath Utility Method</h2>

<p>A reusable utility method can generate dynamic XPath locators.</p>

<pre><code>public By productLocator(String productName) {

 

    String xpath =

        "//div[contains(@class,'product-card')][.//h2[normalize-space()='"

        + productName + "']]";

 

    return By.xpath(xpath);

}</code></pre>

<p>The test can then use:</p>

<pre><code>driver.findElement(

    productPage.productLocator("Laptop")

).click();</code></pre>

<hr>

<h2>63. Handling Quotes in Dynamic XPath</h2>

<p>Special care is required when dynamic values contain quotes because XPath strings use single or double quotation marks.</p>

<p>For example:</p>

<pre><code>String text = "Men's Shoes";</code></pre>

<p>A simple XPath concatenation may require special handling when the data itself contains an apostrophe.</p>

<p>In a mature automation framework, XPath construction utilities can be used to safely create XPath string expressions for arbitrary text.</p>

<hr>

<h2>64. XPath concat() Function</h2>

<p>The <strong>concat()</strong> function can combine multiple strings in XPath.</p>

<pre><code>concat('Men', "'", 's Shoes')</code></pre>

<p>This can be useful when a target text contains both single and double quote characters and a normal XPath string literal is insufficient.</p>

<hr>

<h2>65. Dynamic XPath with Class Tokens</h2>

<p>HTML class attributes can contain multiple class names:</p>

<pre><code>&lt;button class="btn btn-primary login-button"&gt;Login&lt;/button&gt;</code></pre>

<p>A common approach is:</p>

<pre><code>//button[contains(@class,'login-button')]</code></pre>

<p>For strict class-token matching, a normalized class expression can be used:</p>

<pre><code>//button[contains(concat(' ', normalize-space(@class), ' '), ' login-button ')]</code></pre>

<p>This reduces the risk of accidentally matching a class whose name merely contains the same characters.</p>

<hr>

<h2>66. Dynamic XPath for Unique Elements</h2>

<p>A good dynamic XPath should ideally identify one intended element. Before using a locator in Selenium, validate that it uniquely identifies the desired element in the current DOM.</p>

<pre><code>//input[@name='username']</code></pre>

<p>If this matches multiple elements, add another stable condition:</p>

<pre><code>//form[@id='loginForm']//input[@name='username']</code></pre>

<hr>

<h2>67. XPath Validation in Browser Developer Tools</h2>

<p>Chrome and other modern browsers provide developer tools that can be used to inspect the DOM and test XPath expressions.</p>

<p>In Chrome DevTools, an XPath can commonly be tested from the Console using:</p>

<pre><code>$x("//button[contains(text(),'Login')]")</code></pre>

<p>This helps determine whether an XPath matches the intended element before adding it to Selenium code.</p>

<hr>

<h2>68. Dynamic XPath Debugging Process</h2>

<p>When a dynamic XPath fails, use a systematic debugging process:</p>

<ol>

<li>Inspect the current HTML.</li>

<li>Check whether the element exists.</li>

<li>Verify the XPath syntax.</li>

<li>Test the XPath in browser developer tools.</li>

<li>Check whether multiple elements are matched.</li>

<li>Check whether the element is inside an iframe.</li>

<li>Check whether the element is dynamically rendered.</li>

<li>Check whether an explicit wait is required.</li>

<li>Check whether the DOM changes after the page loads.</li>

<li>Update the locator using stable attributes or relationships.</li>

</ol>

<hr>

<h2>69. Common Mistakes in Dynamic XPath</h2>

<ul>

<li>Using complete dynamic IDs.</li>

<li>Depending on unstable generated class names.</li>

<li>Using overly long absolute XPath expressions.</li>

<li>Using indexes when a stable attribute exists.</li>

<li>Using text that changes frequently.</li>

<li>Creating XPath expressions that match multiple elements.</li>

<li>Ignoring whitespace differences.</li>

<li>Ignoring iframe boundaries.</li>

<li>Using XPath to solve a synchronization problem.</li>

<li>Using complex XPath when a simpler stable locator is available.</li>

<li>Hard-coding dynamic values that should come from test data.</li>

</ul>

<hr>

<h2>70. Best Practices for Dynamic XPath</h2>

<ul>

<li>Prefer stable attributes whenever possible.</li>

<li>Use meaningful application-specific attributes such as <code>data-testid</code> when available.</li>

<li>Use <code>contains()</code> for stable portions of changing attributes.</li>

<li>Use <code>starts-with()</code> when an attribute has a predictable prefix.</li>

<li>Use text carefully when visible text is stable.</li>

<li>Use parent-child relationships when direct attributes are unavailable.</li>

<li>Use sibling relationships for label-field structures.</li>

<li>Avoid unnecessary XPath complexity.</li>

<li>Validate uniqueness before using a locator.</li>

<li>Use explicit waits for dynamically rendered elements.</li>

<li>Keep locators inside Page Object classes.</li>

<li>Use reusable methods for frequently generated dynamic XPath expressions.</li>

<li>Avoid relying on fragile indexes.</li>

<li>Keep test data separate from locator logic.</li>

</ul>

<hr>

<h2>71. Dynamic XPath vs CSS Selector</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Feature</th><th>Dynamic XPath</th><th>CSS Selector</th></tr>

<tr><td>Partial attribute matching</td><td>Yes</td><td>Yes</td></tr>

<tr><td>Text-based location</td><td>Yes</td><td>Not directly</td></tr>

<tr><td>Parent traversal</td><td>Yes</td><td>More limited depending on selector capabilities</td></tr>

<tr><td>Sibling navigation</td><td>Yes</td><td>Yes for many cases</td></tr>

<tr><td>Complex DOM relationships</td><td>Strong</td><td>Good but different syntax</td></tr>

<tr><td>Learning complexity</td><td>Higher</td><td>Often simpler for straightforward selectors</td></tr>

</table>

<p>Neither XPath nor CSS is universally preferable. The locator should be selected based on stability, readability, uniqueness, and the application's DOM.</p>

<hr>

<h2>72. Dynamic XPath vs ID Locator</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>ID Locator</th><th>Dynamic XPath</th></tr>

<tr><td>Very simple when ID is stable.</td><td>Useful when IDs change dynamically.</td></tr>

<tr><td>Usually concise.</td><td>Can express complex relationships.</td></tr>

<tr><td>Fast and readable.</td><td>Flexible for dynamic structures.</td></tr>

<tr><td>Depends on stable ID.</td><td>Can use stable portions of attributes or DOM relationships.</td></tr>

</table>

<hr>

<h2>73. Practical Login Automation Example</h2>

<pre><code>import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

 

public class DynamicXPathLoginTest {

 

    public static void main(String[] args) {

 

        WebDriver driver = new ChromeDriver();

 

        driver.get("https://example.com/login");

 

        String usernameXPath =

            "//input[starts-with(@id,'username_')]";

 

        String passwordXPath =

            "//input[starts-with(@id,'password_')]";

 

        String loginButtonXPath =

            "//button[contains(text(),'Login')]";

 

        driver.findElement(By.xpath(usernameXPath))

                .sendKeys("admin");

 

        driver.findElement(By.xpath(passwordXPath))

                .sendKeys("admin123");

 

        driver.findElement(By.xpath(loginButtonXPath))

                .click();

 

        driver.quit();

    }

}</code></pre>

<hr>

<h2>74. Practical E-Commerce Example</h2>

<p>Suppose an e-commerce application displays multiple products:</p>

<pre><code>Laptop

Mobile

Tablet

Headphones</code></pre>

<p>A dynamic XPath can select a product based on its name:</p>

<pre><code>String product = "Laptop";

 

String xpath =

    "//div[contains(@class,'product-card')][.//h2[normalize-space()='"

    + product + "']]";

 

driver.findElement(By.xpath(xpath)).click();</code></pre>

<p>The same code can select another product simply by changing the test data.</p>

<hr>

<h2>75. Practical Dynamic Table Example</h2>

<pre><code>String username = "John";

 

String rowXPath =

    "//table//tr[td[normalize-space()='" + username + "']]";

 

String editButtonXPath =

    rowXPath + "//button[contains(text(),'Edit')]";

 

driver.findElement(By.xpath(editButtonXPath)).click();</code></pre>

<p>This approach is useful when a table contains many rows and the required row must be selected based on its data rather than its fixed position.</p>

<hr>

<h2>76. Dynamic XPath with TestNG DataProvider</h2>

<pre><code>@DataProvider(name = "users")

public Object[][] users() {

    return new Object[][] {

        {"John"},

        {"David"},

        {"Robert"}

    };

}

 

@Test(dataProvider = "users")

public void userTest(String username) {

 

    String xpath =

        "//div[contains(@class,'user-card')][.//span[normalize-space()='"

        + username + "']]";

 

    driver.findElement(By.xpath(xpath)).click();

}</code></pre>

<p>This demonstrates how Dynamic XPath and Data Providers can work together to test multiple records with one reusable test method.</p>

<hr>

<h2>77. Dynamic XPath with Page Object Model</h2>

<p>In a POM-based framework, dynamic XPath should be encapsulated inside page classes.</p>

<pre><code>public class UserPage {

 

    private WebDriver driver;

 

    public UserPage(WebDriver driver) {

        this.driver = driver;

    }

 

    public void selectUser(String username) {

 

        String xpath =

            "//div[contains(@class,'user-card')][.//span[normalize-space()='"

            + username + "']]";

 

        driver.findElement(By.xpath(xpath)).click();

    }

}</code></pre>

<p>The test class can then simply call:</p>

<pre><code>userPage.selectUser("John");</code></pre>

<p>This keeps XPath construction and Selenium interaction logic inside the page object.</p>

<hr>

<h2>78. Real-World Dynamic XPath Architecture</h2>

<pre><code>Application DOM

      |

      v

Inspect Element

      |

      v

Identify Stable Attribute

      |

      +--------------------+

      |                    |

      v                    v

Stable Text          Stable Attribute

      |                    |

      +---------+----------+

                |

                v

        Dynamic XPath

                |

                v

        Validate in DOM

                |

                v

         Selenium By.xpath()

                |

                v

          WebElement

                |

                v

          Web Interaction

                |

                v

             Assertion</code></pre>

<hr>

<h2>79. Dynamic XPath Learning Roadmap</h2>

<ol>

<li>Understand HTML DOM structure.</li>

<li>Learn basic XPath syntax.</li>

<li>Understand relative XPath.</li>

<li>Learn XPath attributes.</li>

<li>Learn <code>contains()</code>.</li>

<li>Learn <code>starts-with()</code>.</li>

<li>Learn <code>text()</code>.</li>

<li>Learn <code>normalize-space()</code>.</li>

<li>Learn XPath axes.</li>

<li>Practice parent-child relationships.</li>

<li>Practice sibling relationships.</li>

<li>Practice dynamic tables.</li>

<li>Practice dynamic product lists.</li>

<li>Combine XPath with Selenium waits.</li>

<li>Use Dynamic XPath with Page Object Model.</li>

<li>Use Dynamic XPath with Data Providers.</li>

<li>Build reusable XPath utility methods.</li>

</ol>

<hr>

<h2>80. Interview Questions on Dynamic XPath</h2>

<h3>1. What is Dynamic XPath?</h3>

<p>Dynamic XPath is an XPath expression designed to locate elements whose attributes, text, or DOM position may change dynamically.</p>

<h3>2. Why is Dynamic XPath used in Selenium?</h3>

<p>It helps Selenium locate elements reliably when static attributes such as generated IDs or changing class names are not stable.</p>

<h3>3. What is the difference between static and dynamic XPath?</h3>

<p>Static XPath generally depends on exact fixed values, while dynamic XPath can use partial values, functions, or DOM relationships to handle changing elements.</p>

<h3>4. What is contains() in XPath?</h3>

<p><code>contains()</code> matches an element when a specified substring appears inside an attribute or text value.</p>

<h3>5. What is starts-with()?</h3>

<p><code>starts-with()</code> matches an attribute whose value begins with a specified string.</p>

<h3>6. Can XPath locate an element using text?</h3>

<p>Yes. The <code>text()</code> function can be used to locate elements based on their visible text.</p>

<h3>7. What is normalize-space()?</h3>

<p><code>normalize-space()</code> removes leading and trailing whitespace and normalizes sequences of whitespace characters for XPath string comparison.</p>

<h3>8. Can Dynamic XPath handle changing IDs?</h3>

<p>Yes. Functions such as <code>contains()</code> and <code>starts-with()</code> can identify the stable portion of a dynamic ID.</p>

<h3>9. Can Dynamic XPath locate table rows?</h3>

<p>Yes. XPath can locate rows using cell values and then navigate to other cells or controls within the row.</p>

<h3>10. Can Dynamic XPath be used with Page Object Model?</h3>

<p>Yes. Dynamic XPath can be stored and generated inside Page Object classes.</p>

<h3>11. Can XPath use multiple conditions?</h3>

<p>Yes. XPath supports conditions using operators such as <code>and</code> and <code>or</code>.</p>

<h3>12. What is an XPath axis?</h3>

<p>An XPath axis describes a relationship between nodes, such as parent, child, ancestor, descendant, following-sibling, and preceding-sibling.</p>

<h3>13. How do you locate a button based on partial text?</h3>

<pre><code>//button[contains(text(),'Login')]</code></pre>

<h3>14. How do you locate an element whose ID starts with a value?</h3>

<pre><code>//input[starts-with(@id,'user_')]</code></pre>

<h3>15. How do you locate an element relative to another element?</h3>

<p>Use XPath relationships such as parent, child, ancestor, descendant, following-sibling, or preceding-sibling.</p>

<h3>16. Should indexes always be used in Dynamic XPath?</h3>

<p>No. Indexes should be used only when necessary because DOM ordering can change.</p>

<h3>17. Can Dynamic XPath be combined with DataProvider?</h3>

<p>Yes. DataProvider values can be inserted into XPath expressions to locate different records dynamically.</p>

<h3>18. Can Dynamic XPath work with POM?</h3>

<p>Yes. POM is a good place to encapsulate reusable dynamic locator logic.</p>

<h3>19. Does Dynamic XPath solve synchronization issues?</h3>

<p>No. XPath identifies an element, while synchronization should be handled using appropriate waits when the element is not immediately available or interactable.</p>

<h3>20. What is the most important rule for Dynamic XPath?</h3>

<p>The locator should be based on stable, meaningful information and should uniquely identify the intended element whenever practical.</p>

<hr>

<h2>81. Quick Reference Table</h2>

<table border="1" cellpadding="8" cellspacing="0">

<tr><th>Technique</th><th>Example</th><th>Purpose</th></tr>

<tr><td>Exact Attribute</td><td><code>//input[@id='username']</code></td><td>Stable exact attribute</td></tr>

<tr><td>contains()</td><td><code>//input[contains(@id,'user')]</code></td><td>Partial attribute match</td></tr>

<tr><td>starts-with()</td><td><code>//input[starts-with(@id,'user_')]</code></td><td>Dynamic prefix</td></tr>

<tr><td>text()</td><td><code>//button[text()='Login']</code></td><td>Exact visible text</td></tr>

<tr><td>contains text</td><td><code>//button[contains(text(),'Login')]</code></td><td>Partial visible text</td></tr>

<tr><td>normalize-space()</td><td><code>//button[normalize-space()='Login']</code></td><td>Whitespace normalization</td></tr>

<tr><td>Parent</td><td><code>//input/parent::div</code></td><td>Move to parent</td></tr>

<tr><td>Child</td><td><code>//div/child::input</code></td><td>Move to child</td></tr>

<tr><td>Ancestor</td><td><code>//input/ancestor::form</code></td><td>Move to ancestor</td></tr>

<tr><td>Descendant</td><td><code>//div[@id='form']//input</code></td><td>Find nested elements</td></tr>

<tr><td>Following-Sibling</td><td><code>//label/following-sibling::input</code></td><td>Locate next sibling</td></tr>

<tr><td>Preceding-Sibling</td><td><code>//input/preceding-sibling::label</code></td><td>Locate previous sibling</td></tr>

<tr><td>Index</td><td><code>(//button)[2]</code></td><td>Select by position</td></tr>

<tr><td>last()</td><td><code>//tr[last()]</code></td><td>Select last match</td></tr>

</table>

<hr>

<h2>82. Practical Exercises</h2>

<ol>

<li>Create a Dynamic XPath for an input whose ID changes on every page load.</li>

<li>Create a Dynamic XPath using <code>contains()</code>.</li>

<li>Create a Dynamic XPath using <code>starts-with()</code>.</li>

<li>Locate a button using partial text.</li>

<li>Locate an input relative to a label.</li>

<li>Locate a product card using the product name.</li>

<li>Locate a price from a specific product row.</li>

<li>Locate a specific user in a dynamic table.</li>

<li>Click an Edit button inside a selected table row.</li>

<li>Use Dynamic XPath with TestNG DataProvider.</li>

<li>Create a reusable Dynamic XPath method inside a Page Object.</li>

<li>Test XPath expressions using browser developer tools.</li>

<li>Combine Dynamic XPath with explicit waits.</li>

<li>Create a mini Selenium project using dynamic product locators.</li>

</ol>

<hr>

<h2>83. Summary</h2>

<p>Dynamic XPath is an important Selenium skill for locating elements whose attributes, text, or positions change dynamically. Instead of depending entirely on fixed IDs or complete DOM paths, Dynamic XPath allows testers to use stable portions of attributes, partial text, XPath functions, and relationships between elements.</p>

<p>The most commonly used Dynamic XPath techniques include <strong>contains()</strong>, <strong>starts-with()</strong>, <strong>text()</strong>, <strong>normalize-space()</strong>, parent-child relationships, ancestor-descendant relationships, sibling relationships, and indexed expressions.</p>

<p>Dynamic XPath becomes particularly powerful when combined with Selenium WebDriver, explicit waits, Page Object Model, TestNG Data Providers, and data-driven automation. A well-designed locator should be readable, stable, sufficiently specific, and maintainable.</p>

<p><strong>Final Takeaway:</strong> The goal of Dynamic XPath is not to create the most complicated XPath possible. The goal is to create a simple and reliable locator based on stable information in the application's DOM.</p>

<hr>

<h2>84. Course Resources</h2>

<p>Learn more about Selenium WebDriver, XPath, TestNG, Page Object Model, data-driven testing, and automation frameworks:</p>

<ul>

<li><a href="https://www.justacademy.co/course-detail/selenium-training" target="_blank" rel="noopener noreferrer">Selenium Training</a></li>

<li><a href="https://www.justacademy.co/register-for-course-demo" target="_blank" rel="noopener noreferrer">Register for Selenium Course Demo</a></li>

</ul>

<p>JustAcademy's Selenium course covers Selenium WebDriver, XPath and CSS selectors, dynamic web elements, TestNG, data-driven testing, Page Object Model, framework development, reporting, and practical automation workflows. :contentReference[oaicite:0]{index=0}</p>

</div>

Previous Next
whatsapp